package com.yuyou.fn.timer.task;

import com.github.wens.mybatisplus.examples.Example;
import com.google.common.collect.Collections2;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHander;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.report.entity.StudentBalance;
import com.yuyou.fn.report.entity.MergeStudentRegDetail;
import com.yuyou.fn.report.service.IStudentBalanceService;
import com.yuyou.fn.report.service.IMergeStudentRegDetailService;
import com.yuyou.fn.report.vo.StudentRegDetailQueryVo;
import com.yuyou.fn.settlement.entity.MainAccount;
import com.yuyou.fn.settlement.service.IMainAccountService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by Administrator on 2018/4/9.
 */
@JobHander(value = "StudentBalanceTask")
@Component
public class StudentBalanceTask extends IJobHandler {

    @Resource
    private IMainAccountService mainAccountService;

    @Resource
    private IStudentService studentService;

    @Resource
    private IMergeStudentRegDetailService mergeStudentRegDetailService;

    @Resource
    private IStudentRefundService studentRefundService;

    @Resource
    private IChangeClassService changeClassService;

    @Resource
    private IPeriodService periodService;

    @Resource
    private IStudentBalanceService studentBalanceService;

    @Override
    public ReturnT<String> execute(String... params) throws Exception {
        Example<StudentBalance> studentBalanceExample=StudentBalance.createExample();
        studentBalanceService.deleteByExample(studentBalanceExample);

        Example<Period> example=Period.createExample();
        List<Period> periods = periodService.findListByExample(example);
        Map<Long, Period> periodMap = BeanUtils.toMap(periods, "periodId");
        List<MainAccount> mainAccountList=mainAccountService.findBigZeroStudentBalance();
        List<StudentBalance> studentBalanceList=new ArrayList<>(200);
        List<Long> studentIdList=new ArrayList<>(200);
        for (MainAccount mainAccount:mainAccountList){
            StudentBalance studentBalance=new StudentBalance();
            studentBalance.setStudentId(mainAccount.getMainAccountId());
            studentBalance.setBalanceAmount(mainAccount.getBalanceAmount());
            studentBalanceList.add(studentBalance);
            studentIdList.add(mainAccount.getMainAccountId());
            if (studentBalanceList.size()>=200){
                this.saveStudentBalance(periodMap,studentIdList,studentBalanceList);
                studentBalanceList.clear();
                studentIdList.clear();
            }
        }
        if (studentBalanceList.size()>0){
            this.saveStudentBalance(periodMap,studentIdList,studentBalanceList);
        }

        return ReturnT.SUCCESS;
    }

    public void saveStudentBalance(Map<Long,Period> periodMap,List<Long> studentIdList,List<StudentBalance> studentBalanceList){
            List<Student> studentList=studentService.findByIds(studentIdList);
            Map<Long, Student> studentMap = BeanUtils.toMap(studentList, "studentId");
            StudentRegDetailQueryVo studentRegDetailQueryVo=new StudentRegDetailQueryVo();
            studentRegDetailQueryVo.setRegStatus(0);
            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByStudentIdsQueryVo(studentIdList,studentRegDetailQueryVo,"regId","periodId","studentId");
            Map<Long, List<MergeStudentRegDetail>> studentRegDetailMap = BeanUtils.toGroup(mergeStudentRegDetailList, "studentId");
            List<StudentRefund> studentRefundList=studentRefundService.findToBalanceRefundByStudentIds(studentIdList,"studentRegId","periodId","studentId");
            List<Long> studentRegIds = BeanUtils.toList(studentRefundList, "studentRegId");
            studentRegIds=Utils.removeDuplicate(studentRegIds);
            List<ChangeClass> changeClassList=changeClassService.findChangeClassByRegIds(studentRegIds,"changeClassId","regId");
            Map<Long, List<ChangeClass>> changeClassMap = BeanUtils.toGroup(changeClassList, "regId");

            Collection<StudentRefund> studentRefundCollection= Collections2.filter(studentRefundList,c->!changeClassMap.containsKey(c.getStudentRegId()));
            studentRefundList=new ArrayList<>(studentRefundCollection);
            Map<Long,List<StudentRefund>> studentRefundMap=BeanUtils.toGroup(studentRefundList,"studentId");
            for (StudentBalance save:studentBalanceList){
                save.setUpdateTime(TimeUtils.now());
                save.setCreateTime(TimeUtils.now());
                Long studentId=save.getStudentId();
                Student student=studentMap.get(studentId);

                save.setStudentPhoneNo(student.getPhoneNo());
                save.setStudentNo(student.getStudentNo());
                save.setStudentName(student.getName());
                save.setLastCampusId(student.getLastRegCampusId());
                save.setLastCampusName(student.getLastRegCampusName());
                save.setGradeId(student.getGradeId());
                save.setGradeName(student.getGradeName());
                save.setSchool(student.getSchool());
                List<MergeStudentRegDetail> oneRegList=studentRegDetailMap.get(studentId);
                List<Long> periodIds = BeanUtils.toList(oneRegList, "periodId");
                periodIds=Utils.removeDuplicate(periodIds);
                List<Period> periodList=this.periodIdToDetailMax4(periodIds,periodMap);
                save.setRegPeriodIds(StringUtils.join(BeanUtils.toList(periodList,"periodId"),","));
                save.setRegPeriodNames(StringUtils.join(BeanUtils.toList(periodList,"periodName"),","));
                List<StudentRefund> studentRefunds=studentRefundMap.get(studentId);
                periodIds = BeanUtils.toList(studentRefunds, "periodId");
                periodList=this.periodIdToDetailMax4(periodIds,periodMap);
                save.setRefundPeriodIds(StringUtils.join(BeanUtils.toList(periodList,"periodId"),","));
                save.setRefundPeriodNames(StringUtils.join(BeanUtils.toList(periodList,"periodName"),","));
        }
        studentBalanceService.insertBatch(studentBalanceList);
    }

    public List<Period> periodIdToDetailMax4(List<Long> periodIds,Map<Long,Period> periodMap){
        List<Period> periodList=new ArrayList<>(periodIds.size());
        for (Long periodId:periodIds){
            periodList.add(periodMap.get(periodId));
        }
        Collections.sort(periodList, new Comparator<Period>() {
            @Override
            public int compare(Period o1, Period o2) {
                return o2.getPeriodNo().compareTo(o1.getPeriodNo());
            }
        });
        List<Period> periodList4=new ArrayList<>(4);
        for (int i=0;i<periodList.size() && i<4;i++){
            periodList4.add(periodList.get(i));
        }
        return periodList4;

    }
}
